package com.du.fileload.framework.servlet;

import com.du.fileload.framework.utils.FileUploadUtils;
import com.du.plugin.common.tool.HandleException;
import com.du.plugin.common.tool.MD5;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

public class RegisterFileRequestServlet extends HttpServlet {

    private static final Logger log = LoggerFactory.getLogger(RegisterFileRequestServlet.class);

    private final String ResponseFileKey="File-Level";

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //getServletConfig()
        Long logId = System.currentTimeMillis();
        String requestUrl = req.getRequestURI();
        // 使用浏览器缓存
        if (req.getHeader("If-Modified-Since") != null || req.getHeader("If-None-Match") != null) {
            resp.setStatus(304);
            return;
        }
        log.info(String.format("--%s 拦截到文件请求: %s 参数: %s", logId, requestUrl, req.getQueryString()));
        if (!requestUrl.contains(".")) {
            log.info(String.format("--%s 文件响应失败: %s 参数: %s  -原因: url wrongful", logId, requestUrl, req.getQueryString()));
            resp.getWriter().write("url wrongful: " + requestUrl);
            return;
        }
        //获取请求参数
        String force = req.getParameter("force");//=true强制检查指定级别图片
        String level = req.getParameter("level");//图片加载质量级别
        //重组文件名 带后缀
        String cfileNameSuffix = requestUrl.substring(requestUrl.lastIndexOf("/") + 1);
        //源文件名 不带后缀  不带x1
        String cfileName = cfileNameSuffix.substring(0, cfileNameSuffix.indexOf("_"));
        String suffix = FilenameUtils.getExtension(cfileNameSuffix);

        //检查源文件是否存在
        String filePath = FileUploadUtils.getAbsolPathFileName(requestUrl.replace(cfileNameSuffix, String.format("%s.%s", cfileName, suffix)));
        File file = new File(filePath);
        if (!file.exists()) {
            //加载出错图片
            log.info(String.format("--%s 文件响应失败: %s 参数: %s  -原因: resource not found", logId, requestUrl, req.getQueryString()));
            //resp.getWriter().write("resource not found: " + requestUrl);
            resp.setStatus(404);
            return;
        }
        //未指定质量级别则使用源文件相应
        if (level == null) {
            //直接加载源文件
            log.info(String.format("--%s 文件响应成功(源文件): %s 参数: %s ", logId, requestUrl, req.getQueryString()));
            resp.addHeader(ResponseFileKey,"0");
            outPutFile(resp, requestUrl,file);
            return;
        }
        //首先查询知道级别是否存在
        //通过定制的文件名进行一级识别
        if (!cfileNameSuffix.contains(String.format("_x%s", level))) {
            //强制检查指定质量级别是否存在 否则用源文件响应
            if(force==null||!force.trim().equals("true")) {
                //检查失败，加载原图
                log.info(String.format("--%s 文件响应成功(源文件): %s 参数: %s ", logId, requestUrl, req.getQueryString()));
                resp.addHeader(ResponseFileKey,"0");
                outPutFile(resp,requestUrl, file);
                return;
            }
        }

        //按需加载
        String requestFileName = String.format("%s_x%s.%s", cfileName, level, suffix);
        filePath = FileUploadUtils.getAbsolPathFileName(requestUrl.replace(cfileNameSuffix, requestFileName));
        file = new File(filePath);
        if (!file.exists()) {
            //检查失败，加载原图
            log.info(String.format("--%s 文件响应成功(源文件): %s 参数: %s ", logId, requestUrl, req.getQueryString()));
            resp.addHeader(ResponseFileKey,"0");
            outPutFile(resp, requestUrl,file);
            return;
        }
        log.info(String.format("--%s 文件响应成功(x%s): %s 参数: %s ", logId,level, requestUrl, req.getQueryString()));
        resp.addHeader(ResponseFileKey,level);
        outPutFile(resp,requestUrl, file);

    }


    public static final void outPutFile(HttpServletResponse response,String url, File outFile) {
        // 非304情况下的操作 使用浏览器缓存
        response.setHeader("ETag", MD5.md5(url));// 这里假设的是根据不同的id
        response.setHeader("Cache-Control", "private");
        try (FileInputStream fileInputStream = new FileInputStream(outFile); OutputStream outputStream = response.getOutputStream();) {
            // 未指定压缩参数则输出原文件
            response.setContentType("image/jpg"); // 设置返回的文件类型
            response.setContentLength((int) outFile.length());
            response.setHeader("Access-Control-Allow-Origin", "*");// 设置该图片允许跨域访问
            IOUtils.copy(fileInputStream, outputStream);
        } catch (Exception e) {
            HandleException.addEx(e);
            try {
                response.sendError(500, e.getMessage());
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }

}
